public class Code {
    // 最长湍流子数组

    public int maxTurbulenceSize(int[] arr) {
        // 创建 dp 表
        // 初始化
        // 填表
        // 返回值

        // 简单分析题目创建出一个 dp 表
        // dp[i] 表示的是以 i 位置元素为结尾的所有子数组中，最长的湍流数组长度（但其实这是一个错误的创建）
        // 正确的分析题目，应该要注意到问题中存在可能的三种状态
        // 上升、下降、相等
        // 对此我们需要创建出两个 dp 表来分别对应两种情况
        int n = arr.length;
        // f[i] 表示，以 i 为结尾的所有子数组中，最后呈现“上升”状态下的最长长度
        int[] f = new int[n];
        // g[i] 表示，以 i 为结尾的所有子数组中，最后呈现“下降”状态下的最长长度
        int[] g = new int[n];

        // 进行初始化
        // 这里的初始化是将两个数组中的元素都初始化为 1 ，具体原因看填表操作
        for(int j = 0; j < n; j++){
            f[j] = g[j] = 1;
        }

        // 进行填表操作
        // 这里的填表顺序是两个表同时填写，从左向右
        for(int i = 1; i < n; i++){
            // 针对 f “上升” 趋势表的填写进行简单分析，存在三种可能的情况
            // 我们假设 (i - 1，i) 位置的数字分别对应 (a，b)
            // 当 a > b 此时呈现的是 “下降” 趋势，要在 f[i] 中实现 “上升” 趋势，就需要这个数字自身作为一个 “上升” 的起点
            // 当 a < b 此时呈现的是 “上升” 趋势，就需要 g[i - 1] 表示下降位置的数据加上当前的 1 位数
            // 当 a = b 此时两数相等，同样的，自身作为上升的起点，我们将其记录为 1
            if(arr[i] < arr[i - 1]){
                f[i] = g[i - 1] + 1;
            }else if(arr[i] > arr[i - 1]){
                // 这里 g 表的填写与 f 表的填写逻辑反过来即可
                g[i] = f[i - 1] + 1;
            }
            // 很明显，初始化时将值全部初始化为 1 可以简化填表时的代码量
        }
        // 填写返回值
        // 这里的返回值就是 f 表和 g 表中包含的最大值
        int ret = 0;
        for(int j = 0; j < n; j++){
            ret = Math.max(ret, Math.max(f[j], g[j]));
        }
        return ret;
    }
}
